<script setup lang="ts">
import {Api} from '@/api/type'
import {onMounted, ref, watch} from 'vue'
import {BaseApi} from '@/api/base-api'
import {NInput, NPopselect, NTree} from 'naive-ui'
import {TreeOption} from 'naive-ui/es/tree/src/interface'
// -------------------------------------------------
type R<T> = Api.Common.R<T>;
type Data = Api.System.Dept;
// -------------------------------------------------
const emit = defineEmits<{
    select: [data: {key: string | number; label: string;}]
}>()

interface Option {
    key: string
    label: string
    parent: string
    children?: Array<Option>
}

const baseApi = new BaseApi<Data>('dept')
const treeData = ref<Array<Option>>([])
const pattern = ref<string>('')
const expandAll = ref<string>('1')
/**
 * 组装用户路由树
 */
const generateTree = (list: Array<Data>): Array<Option> => {
    let optionList: Array<Option> = JSON.parse(JSON.stringify(list))
        .map((item: Data): Option => {
            return {
                key: item.identity,
                label: item.name,
                parent: item.parent
            } as Option
        })

    let _map: Map<string, Option> = optionList.reduce((map: Map<string, Option>, item: Option) => {
        map.set(item.key, item)
        return map
    }, new Map<string, Option>())

    optionList.forEach((item: Option) => {
        let parent: Option | undefined = _map.get(item.parent)
        let current: Option | undefined = _map.get(item.key)
        if (parent) {
            if (!parent?.children) {
                parent.children = []
            }
            if (current) {
                parent.children.push(current)
            }
            _map.set(item.parent, parent)
        }
    })
    return optionList.filter((item: Option): boolean => item.parent == '0')
}

async function initialize() {
    let result: R<Array<Data>> = await baseApi.getDataList()
    if (result.code == 0) {
        treeData.value = generateTree(result.data || [])
    }
}

function nodeProps({option}: {option: TreeOption}) {
    return {
        style: '--n-line-color: #aaaaaa;--n-node-content-height: 34px;',
        onClick() {
            console.info(option)
            emit('select', {key: option.key || '', label: option.label || ''})
        }
    }
}

watch(expandAll, (value) => {
    console.info(value)
})

defineExpose({
    initialize
})

onMounted(() => {
    initialize()
})
</script>

<template>
    <div>
        <div class="flex gap-col-2 items-center">
            <NInput class="flex-1" clearable v-model:value="pattern" placeholder="搜索" />
            <NPopselect v-model:value="expandAll" :options="[{label: '展开全部',value: '1'},{label: '折叠全部',value: '2'}]">
                <svg class="w-6 h-6 inline-block cursor-pointer outline-0" width="32" height="32" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
                    <circle cx="24" cy="12" r="3" fill="currentColor" />
                    <circle cx="24" cy="24" r="3" fill="currentColor" />
                    <circle cx="24" cy="35" r="3" fill="currentColor" />
                </svg>
            </NPopselect>
        </div>
        <n-tree
            block-line
            show-line
            :data="treeData"
            :pattern="pattern"
            :node-props="nodeProps as any"
            :show-irrelevant-nodes="true"
            :default-expand-all="expandAll == '1'"
        />
    </div>
</template>
